"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.copyText = exports.listToTree = exports.treeToList = exports.uniqueArray = exports.deepClone = exports.useThrottle = exports.useDebounce = exports.isNull = exports.isUndefined = exports.isBlob = exports.isFile = exports.isObject = exports.isBoolean = exports.isDate = exports.isFunction = exports.isArray = exports.isNumber = exports.isString = exports.dataType = void 0;
/* 类型判断 */
function dataType(v) {
    if (typeof v === "boolean")
        return "boolean";
    else if (typeof v === "string")
        return "string";
    else if (typeof v === "number")
        return "number";
    else if (typeof v === "undefined")
        return "undefined";
    else if (v instanceof File)
        return "file";
    else if (v instanceof Blob)
        return "blob";
    else if (v instanceof Array)
        return "array";
    else if (v instanceof Function)
        return "function";
    else if (v instanceof Date)
        return "date";
    else if (v instanceof Object)
        return "object";
    else if (v === null)
        return "null";
    else
        return false;
}
exports.dataType = dataType;
/* 是否为 String */
function isString(v) {
    return dataType(v) === "string";
}
exports.isString = isString;
/* 是否为 Number */
function isNumber(v) {
    return dataType(v) === "number";
}
exports.isNumber = isNumber;
/* 是否为 Array */
function isArray(v) {
    return dataType(v) === "array";
}
exports.isArray = isArray;
/* 是否为 Function */
function isFunction(v) {
    return dataType(v) === "function";
}
exports.isFunction = isFunction;
/* 是否为 Date */
function isDate(v) {
    return dataType(v) === "date";
}
exports.isDate = isDate;
/* 是否为 Boolean */
function isBoolean(v) {
    return dataType(v) === "boolean";
}
exports.isBoolean = isBoolean;
/* 是否为 Object */
function isObject(v) {
    return dataType(v) === "object";
}
exports.isObject = isObject;
/* 是否为 File */
function isFile(v) {
    return dataType(v) === "file";
}
exports.isFile = isFile;
/* 是否为 Blob */
function isBlob(v) {
    return dataType(v) === "blob";
}
exports.isBlob = isBlob;
/* 是否为 undefined */
function isUndefined(v) {
    return dataType(v) === "undefined";
}
exports.isUndefined = isUndefined;
/* 是否为 null */
function isNull(v) {
    return dataType(v) === "null";
}
exports.isNull = isNull;
/* 防抖: 将 fn 封装成防抖函数后返回 */
function useDebounce(fn, delay = 0) {
    let timer;
    return (...params) => {
        clearTimeout(timer);
        timer = setTimeout(() => {
            fn(...params);
        }, delay);
    };
}
exports.useDebounce = useDebounce;
/* 节流: 将 fn 封装为节流函数后返回 */
function useThrottle(fn, delay) {
    /* 使用计时器 */
    let timer; // 计时器
    function delayFn(...params) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!timer) {
                yield fn(...params);
                timer = setTimeout(() => {
                    clearTimeout(timer);
                    timer = 0;
                }, delay);
            }
        });
    }
    /* 使用异步函数 */
    let loading = false; // 是否正在等待
    function loadFn(...params) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!loading) {
                loading = true;
                yield fn(...params);
                loading = false;
            }
        });
    }
    if (isNumber(delay))
        return delayFn;
    else
        return loadFn;
}
exports.useThrottle = useThrottle;
/* 深度克隆对象 */
function deepClone(data) {
    let value;
    // 数组克隆
    if (isArray(data)) {
        value = [];
        data.forEach((v) => {
            value.push(deepClone(v));
        });
    }
    // 对象克隆
    else if (isObject(data)) {
        value = {};
        for (let key in data) {
            value[key] = deepClone(data[key]);
        }
    }
    // 基础类型直接返回
    else
        value = data;
    return value;
}
exports.deepClone = deepClone;
/* 数组去重 */
function uniqueArray(arr) {
    if (isArray(arr)) {
        const set = new Set(arr);
        return Array.from(set);
    }
    else
        return arr;
}
exports.uniqueArray = uniqueArray;
/* 树转列表，并为子节点插入父指针 */
function treeToList(tree, config) {
    const baseConfig = Object.assign({ key: "id", parent: "parent", children: "children", handler: (item) => { } }, (isObject(config) ? config : {}));
    /* 对象参数转为数组 */
    if (isObject(tree))
        tree = [tree];
    if (isArray(tree)) {
        const list = [];
        const pointers = {};
        const { key, parent: parentKey, children: childrenKey, handler } = baseConfig;
        let items = [...tree];
        while (items.length) {
            // 取出当前项
            const current = items.shift();
            // 获取 id, children
            const { [childrenKey]: children = [], [key]: id } = current;
            // 为 children 插入父指针
            const childrenItems = (children || []).map((child) => {
                child[parentKey] = id;
                return child;
            });
            items = [...items, ...childrenItems];
            handler(current);
            list.push(current);
            pointers[id] = current;
        }
        return { value: list, pointers };
    }
    else {
        return false;
    }
}
exports.treeToList = treeToList;
/* 列表转树 */
function listToTree(list, config) {
    const baseConfig = Object.assign({ key: "id", parent: "parent", children: "children", handler: (item) => { } }, (isObject(config) ? config : {}));
    if (isArray(list)) {
        const tree = [];
        const pointers = {};
        const { key, parent: parentKey, children: childrenKey, handler } = baseConfig;
        // 循环节点，设置指针
        list.forEach((item) => {
            const { [key]: id } = item;
            pointers[id] = item;
        });
        // 再次循环节点，插入子节点
        list.forEach((item) => {
            const { [parentKey]: parent } = item;
            handler(item);
            if (pointers[parent]) {
                if (pointers[parent][childrenKey])
                    pointers[parent][childrenKey].push(item);
                else
                    pointers[parent][childrenKey] = [item];
            }
            else {
                tree.push(item);
            }
        });
        return { value: tree, pointers };
    }
    else {
        return false;
    }
}
exports.listToTree = listToTree;
/* 复制文本到剪切版 */
function copyText(text) {
    try {
        /* 使用浏览器自带剪切版功能 */
        return window.navigator.clipboard.writeText(text);
    }
    catch (_a) {
        /* 使用 document.execCommand 剪切 */
        return new Promise((resolve, reject) => {
            try {
                // 创建一个 textarea 储存文本
                const element = document.createElement("textarea");
                element.value = text;
                // 将元素插入到界面外
                element.setAttribute("readonly", "");
                element.style.contain = "strict"; // 告知浏览器不渲染该屏幕外元素
                element.style.position = "absolute";
                element.style.left = "-9999px";
                document.body.appendChild(element);
                // 选中
                element.select();
                // 复制剪切板
                document.execCommand("copy");
                // 清除元素
                document.body.removeChild(element);
                // 存在选中区域时，清除浏览器的选中
                const selection = document.getSelection();
                const originalRange = selection ? selection.rangeCount > 0 && selection.getRangeAt(0) : null;
                if (originalRange) {
                    selection === null || selection === void 0 ? void 0 : selection.removeAllRanges();
                    selection === null || selection === void 0 ? void 0 : selection.addRange(originalRange);
                }
                // 清除激活元素
                const previouslyFocusedElement = document.activeElement;
                if (previouslyFocusedElement)
                    previouslyFocusedElement.focus();
                resolve();
            }
            catch (_a) {
                reject();
            }
        });
    }
}
exports.copyText = copyText;
